package com.puboot.module.blog.controller;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.puboot.common.util.*;
import com.puboot.exception.ArticleNotFoundException;
import com.puboot.module.admin.model.*;
import com.puboot.module.admin.service.*;
import com.puboot.module.admin.vo.ArticleConditionVo;
import com.puboot.module.admin.vo.base.PageResultVo;
import com.puboot.module.admin.vo.base.ResponseVo;
import com.wf.captcha.utils.CaptchaUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.puboot.common.util.CoreConst.THEME_PREFIX;

/**
 * 分类API控制
 * */
@RestController
@Slf4j
@AllArgsConstructor
@RequestMapping("app/api")
public class AppApiController {
    private final BizCategoryService categoryService;
    private final BizArticleService articleService;
    private final BizTagsService tagsService;
    private final SysConfigService configService;
    private final UserService userService;
    private final BizArticleTagsService articleTagsService;
    private final BizCommentService commentService;
    private final BizLoveService loveService;

    /**
     * 获取分类列表 /app/api/categoryList?isFistLevel=true
     * */
    @GetMapping("/categoryList")
    public List<BizCategory> loadCategory(boolean isFistLevel) {
        BizCategory bizCategory = new BizCategory();
        bizCategory.setStatus(CoreConst.STATUS_VALID);
        if (isFistLevel) {
            bizCategory.setPid(CoreConst.TOP_MENU_ID);
        }
        List<BizCategory> catList = null;
        catList = categoryService.list();
        for (BizCategory category:catList) {
            ArticleConditionVo conditionVo = new ArticleConditionVo();
            QueryWrapper<BizArticle> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("category_id",category.getId());
            long count = articleService.count(queryWrapper);
            category.setCount((int)count);
        }
        return catList;
    }
    /**
     * 获取分类详细信息
     * */
    @GetMapping("/category/{id}")
    public BizCategory getCategoryId(@PathVariable("id") Integer id) {
        BizCategory bizCategory = categoryService.getById(id);
        QueryWrapper<BizArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id",id);
        long count = articleService.count(queryWrapper);
        bizCategory.setCount((int)count);
        return bizCategory;
    }

    /**
     * 获取轮播文章
     * */
    @GetMapping("/sliderList")
    public ResponseVo sliderList() {
        List<BizArticle> sliderList =  articleService.sliderList();//轮播文章
        return ResultUtil.success("返回成功",sliderList);
    }

    /**
     * 获取置顶文章列表 categoryId pageNumber pageSize
     * pageNumber: 0
     * pageSize: 8
     * top: true
     * */
    @GetMapping("/articleTopList/{pageNumber}")
    public PageResultVo articleTopList(@PathVariable("pageNumber") Integer pageNumber) {
        ArticleConditionVo vo = new ArticleConditionVo();
        vo.setTop(true);
        vo.setPageNumber(pageNumber);
        IPage<BizArticle> page = new Pagination<>(vo.getPageNumber(), vo.getPageSize());
        List<BizArticle> articleList = articleService.findByCondition(page, vo);
        return ResultUtil.table(articleList, page.getTotal());
    }

    /**
     * 获取文章列表 categoryId pageNumber pageSize
     * pageNumber: 0
     * pageSize: 8
     * top: true categoryId: 1,
     * 					pageNumber: 1,
     * */
    @PostMapping("/articleList")
    public PageResultVo articleList(ArticleConditionVo vo) {
        IPage<BizArticle> page = new Pagination<>(vo.getPageNumber(), vo.getPageSize());
        List<BizArticle> articleList = articleService.findByCondition(page, vo);
        return ResultUtil.table(articleList, page.getTotal());
    }

    /**
     * 站长推荐
     * */
    @GetMapping("/recommendedList")
    public  List<BizArticle> recommendedList() {
        List<BizArticle> articleList = articleService.recommendedList(CoreConst.PAGE_SIZE);
        return articleList;
    }
    /**
     * 最近文章
     * */
    @GetMapping("/recentList")
    public  List<BizArticle> recentList() {
        List<BizArticle> articleList = articleService.recentList(CoreConst.PAGE_SIZE);
        return articleList;
    }
    /**
     * 随机文章
     * */
    @GetMapping("/randomList")
    public  List<BizArticle> randomList() {
        List<BizArticle> articleList = articleService.randomList(CoreConst.PAGE_SIZE);
        return articleList;
    }
    /**
     * 热门文章
     * */
    @GetMapping("/hotList")
    public  List<BizArticle> hotList() {
        List<BizArticle> articleList = articleService.hotList(CoreConst.PAGE_SIZE);
        return articleList;
    }

    /**
     * 文章详情
     * @param articleId
     * @return
     */
    @GetMapping("/article/{articleId}")
    public BizArticle article(@PathVariable("articleId") Integer articleId) {
        BizArticle article = articleService.selectById(articleId);
        if (article == null || CoreConst.STATUS_INVALID.equals(article.getStatus())) {
            throw new ArticleNotFoundException();
        }
       return article;
    }

    /**
     * 标签列表
     * @return
     */
    @PostMapping("tagslist")
    @ResponseBody
    public PageResultVo loadTags(BizTags bizTags, Integer pageNumber, Integer pageSize) {
        IPage<BizTags> bizTagsPage = tagsService.pageTags(bizTags, pageNumber, pageSize);
        List<BizTags> targsList = bizTagsPage.getRecords();
        for (BizTags targ:targsList) {
            QueryWrapper<BizArticleTags> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tag_id",targ.getId());
            long count = articleTagsService.count(queryWrapper);
            targ.setCount((int)count);
            List<BizArticleTags> lisA = articleTagsService.list(queryWrapper);
            targ.setPosts(new ArrayList<BizArticle>());
            if(lisA != null && lisA.size()>0){
                int id = lisA.get(0).getArticleId();
                BizArticle arti = articleService.getById(id);
                if(arti != null) {
                    targ.getPosts().add(arti);
                }
                if(lisA.size()>1) {
                    int id2 = lisA.get(1).getArticleId();
                    BizArticle arti2 = articleService.getById(id2);
                    if (arti2 != null) {
                        targ.getPosts().add(arti2);
                    }
                }
            }
        }
        return ResultUtil.table(targsList, bizTagsPage.getTotal());
    }


    /**
     * 获取标签内容
     * @return
     */
    @GetMapping("getTag/{id}")
    @ResponseBody
    public ResponseVo getTagsById(@PathVariable("id")Integer id) {
        BizTags  tags = tagsService.getById(id);
        if(tags != null) {
            QueryWrapper<BizArticleTags> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tag_id", tags.getId());
            long count = articleTagsService.count(queryWrapper);
            tags.setCount((int) count);
            return ResultUtil.vo(CoreConst.SUCCESS_CODE, null, tags);
        }else
        {
            return ResultUtil.error("未发现标签");
        }
    }


    /**
     * 提交登录
     *
     * @param username
     * @param password
     * @param rememberMe
     * @return
     */
    @PostMapping("/login")
    @ResponseBody
    public ResponseVo login( String username, String password, Integer rememberMe) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            token.setRememberMe(1 == rememberMe);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
        } catch (LockedAccountException e) {
            token.clear();
            return ResultUtil.error("用户已经被锁定不能登录，请联系管理员！");
        } catch (AuthenticationException e) {
            token.clear();
            return ResultUtil.error("用户名或者密码错误！");
        }
        //更新最后登录时间
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        userService.updateLastLoginTime(user);
        return ResultUtil.success("登录成功！",user);
    }
    /**
     * 登出
     * @return
     */
    @RequestMapping("/logout")
    public ResponseVo  logout() {
        Subject subject = SecurityUtils.getSubject();
        if (null != subject) {
            String username = ((User) SecurityUtils.getSubject().getPrincipal()).getUsername();
            Serializable sessionId = SecurityUtils.getSubject().getSession().getId();
            userService.kickout(sessionId, username);
        }
        subject.logout();
        return ResultUtil.success("登出成功！");
    }

    /**
     * 用户列表数据
     */
    @PostMapping("/userList")
    public PageResultVo loadUsers(User user, Integer pageNumber, Integer pageSize) {
        IPage<User> userPage = userService.selectUsers(user, pageNumber, pageSize);
        return ResultUtil.table(userPage.getRecords(), userPage.getTotal());
    }

    /**
     * 网站信息
     */
    @GetMapping("/siteInfo")
    private ResponseVo getSysConfig() {
        Map<String, String> map = configService.selectAll();
        return ResultUtil.success("网站信息获取成功！",map);
    }

    /**
     * 发布评论
     */
    @PostMapping("comment/save")
    public ResponseVo saveComment(HttpServletRequest request, BizComment comment) throws UnsupportedEncodingException {
        if (StrUtil.isEmpty(comment.getNickname())) {
            return ResultUtil.error("请输入昵称");
        }
        Date date = new Date();
        comment.setNickname(HtmlUtil.filter(comment.getNickname()));
        comment.setContent(HtmlUtil.filter(comment.getContent()));
        comment.setIp(HtmlUtil.filter(IpUtil.getIpAddr(request)));
        comment.setCreateTime(date);
        comment.setUpdateTime(date);
        if (StrUtil.isNotBlank(comment.getQq())) {
            comment.setAvatar("http://q1.qlogo.cn/g?b=qq&nk=" + comment.getQq() + "&s=100");
        } else if (StrUtil.isNotBlank(comment.getEmail())) {
            String entry = null;
            try {
                entry = MD5.md5Hex(comment.getEmail());
            } catch (NoSuchAlgorithmException e) {
                log.error("MD5出现异常{}", e.getMessage(), e);
            }
            comment.setAvatar("http://www.gravatar.com/avatar/" + entry + "?d=mp");
        }
        boolean a = commentService.save(comment);
        if (a) {
            return ResultUtil.success("评论提交成功,系统正在审核");
        } else {
            return ResultUtil.error("评论提交失败");
        }
    }
    /**
     * 点赞
     * */
    @PostMapping("love")
    public ResponseVo love(HttpServletRequest request, Integer bizId, Integer bizType) {
        Date date = new Date();
        String ip = IpUtil.getIpAddr(request);
        BizLove bizLove = loveService.checkLove(bizId, ip);
        if (bizLove == null) {
            bizLove = new BizLove();
            bizLove.setBizId(bizId);
            bizLove.setBizType(bizType);
            bizLove.setUserIp(ip);
            bizLove.setStatus(CoreConst.STATUS_VALID);
            bizLove.setCreateTime(date);
            bizLove.setUpdateTime(date);
            loveService.save(bizLove);
            return ResultUtil.success("点赞成功");
        } else {
            return ResultUtil.error("您已赞过了哦~");
        }
    }

}
